/*
 * BitTools.h
 *
 *  Created on: 05/08/2013
 *      Author: marcio
 */

#ifndef BITTOOLS_H_
#define BITTOOLS_H_

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>

#define WORD unsigned long int
#define b_pos(x,i) x & mask1[i]
#define b_on(x,i) x = x | mask1[i]
#define b_off(x,i) x = x | ~(mask1[i])
#define b_count(x) __builtin_popcountl(x)
#define b_first(x) __builtin_ffsl(x)-1
#define b_logW 5
#define b_next(x,i) __builtin_ffsl(x & mask2[i])-1
#define rest 32

WORD mask1[] =
{1u,
2u,
4u,
8u,
16u,
32u,
64u,
128u,
512u,
1024u,
2048u,
4096u,
8192u,
16384u,
32768u,
65536u,
131072u,
262144u,
524288u,
1048576u,
2097152u,
4194304u,
8388608u,
16777216u,
33554432u,
67108864u,
134217728u,
268435456u,
536870912u,
1073741824u,
2147483648u
};

WORD mask2[]=
{2u - 1,
4u - 1,
8u - 1,
16u - 1,
32u - 1,
64u - 1,
128u - 1,
512u - 1,
1024u - 1,
2048u - 1,
4096u - 1,
8192u - 1,
16384u - 1,
32768u - 1,
65536u - 1,
131072u - 1,
262144u - 1,
524288u - 1,
1048576u - 1,
2097152u - 1,
4194304u - 1,
8388608u - 1,
16777216u - 1,
33554432u - 1,
67108864u - 1,
134217728u - 1,
268435456u - 1,
536870912u - 1,
1073741824u - 1,
2147483648u - 1,
4294967296u - 1};

inline void setToSet(WORD* A, long i){
	b_on(A[i >> b_logW], i & rest);
}

inline void setToCompl(WORD* A, long i){
	b_off(A[i >> b_logW], i & rest);
}

inline int setIsIn(WORD* A, long i){
	return b_pos(A[i >> b_logW], i & rest);
}

inline int setIntersec(WORD* A, WORD* B, WORD* C, long from, long to){
	long st = from >> b_logW;
	long end = to >> b_logW;
	int ct = 0;
	long i;
	for( i = st; i < end; i++){
		if((C[i] = B[i] & A[i]) == 0) ct++;
	}
	return ct;
}

inline int setUnio(WORD* A, WORD* B, WORD* C, long from, long to){
	long st = from >> b_logW;
	long end = to >> b_logW;
	int ct = 0;
	long i;
	for( i = st; i < end; i++){
		if((C[i] = B[i] | A[i]) == 0) ct++;
	}
	return ct;
}

inline long setcount(WORD* A, long from, long to){
	long st = from >> b_logW;
	long end = to >> b_logW;
	long ct = 0;
	long i;
	for(i = st; i < end; i++){
		ct += b_count(A[i]);
	}
	return ct;
}

inline void setAllToCompl(WORD* A, long n){
	memset(A, 0, sizeof(WORD)*n);
}

inline void setAllToSet(WORD* A, long n){
	memset(A, 255, sizeof(WORD)*n);
}


#endif /* BITTOOLS_H_ */
